#ifndef __KERNEL_GLOBAL_H
#define __KERNEL_GLOBAL_H

#include "stdint.h"

/* ---------------- GDT描述符属性 ---------------- */

/* 表示段界限4k粒度 */
#define DESC_G_4K                   1    
/* 表示指令有效地址和操作数都是32位 为0则16位 */    
#define DESC_D_32                   1
/* 表示32位字段 */
#define DESC_L                      0     
/* 留给我们使用的 */      
#define DESC_AVL                    0
/* 表示段是否存在位 */
#define DESC_P                      1
/* 段优先级位 */
#define DESC_DPL_0                  0
#define DESC_DPL_1                  1
#define DESC_DPL_2                  2
#define DESC_DPL_3                  3

#define DESC_S_CODE                 1
#define DESC_S_DATA                 DESC_S_CODE
#define DESC_S_SYS                  0
#define DESC_TYPE_CODE              8
#define DESC_TYPE_DATA              2
/* B位置0 不忙 */
#define DESC_TYPE_TSS               9

#define RPL0                        0
#define RPL1                        1
#define RPL2                        2
#define RPL3                        3

#define TI_GDT                      0
#define TI_LDT                      1

#define SELECTOR_K_CODE             ((1 << 3) + (TI_GDT << 2) + RPL0)
#define SELECTOR_K_DATA             ((2 << 3) + (TI_GDT << 2) + RPL0)
#define SELECTOR_K_STACK            SELECTOR_K_DATA
#define SELECTOR_K_VIDEO            ((3 << 3) + (TI_GDT << 2) + RPL0)
/* 第4个段为TSS */
#define SELECTOR_U_CODE             ((5 << 3) + (TI_GDT << 2) + RPL3)
#define SELECTOR_U_DATA             ((6 << 3) + (TI_GDT << 2) + RPL3)
#define SELECTOR_U_STACK            SELECTOR_U_DATA

#define GDT_ATTR_HIGH               ((DESC_G_4K << 7) + (DESC_D_32 << 6) + (DESC_L << 5) + (DESC_AVL << 4))
#define GDT_CODE_ATTR_LOW_DPL3	    ((DESC_P << 7) + (DESC_DPL_3 << 5) + (DESC_S_CODE << 4) + DESC_TYPE_CODE)
#define GDT_DATA_ATTR_LOW_DPL3      ((DESC_P << 7) + (DESC_DPL_3 << 5) + (DESC_S_DATA << 4) + DESC_TYPE_DATA)

struct gdt_desc {
    uint16_t limit_low_word;
    uint16_t base_low_word;
    uint8_t base_mid_byte;
    uint8_t attr_low_byte;
    uint8_t limit_high_attr_high;
    uint8_t base_high_byte;
}; 

/* ---------------- TSS描述符属性 ---------------- */
#define TSS_DESC_D                  0

#define TSS_ATTR_HIGH               ((DESC_G_4K << 7) + (TSS_DESC_D << 6) + (DESC_L << 5) + (DESC_AVL << 4))
#define TSS_ATTR_LOW                ((DESC_P << 7) + (DESC_DPL_0 << 5) + (DESC_S_SYS << 4) + DESC_TYPE_TSS)
#define SELECTOR_TSS                ((4 << 3) + (TI_GDT << 2) + RPL0)


/* ---------------- IDT描述符属性 ---------------- */
#define IDT_DESC_P                  1
#define IDT_DESC_DPL0               0
#define IDT_DESC_DPL1               1
#define IDT_DESC_DPL2               2
#define IDT_DESC_DPL3               3
/* modify by jianglin 2023-11-07 14:42
 * 之前这里对于中断门描述符的类型标志写错了 写成0x0f
 * 0x0f指的是陷阱门，陷阱门同中断门类似，所以也能实现我们之前的效果
 * 但是唯一不同的是 陷阱门不会修改if标志位
 */
#define IDT_DESC_IGD_TYPE           0x0e

#define IDT_DESC_ATTR_DPL0          ((IDT_DESC_P << 7) + (IDT_DESC_DPL0 << 5) + IDT_DESC_IGD_TYPE)
#define IDT_DESC_ATTR_DPL1          ((IDT_DESC_P << 7) + (IDT_DESC_DPL1 << 5) + IDT_DESC_IGD_TYPE)
#define IDT_DESC_ATTR_DPL2          ((IDT_DESC_P << 7) + (IDT_DESC_DPL2 << 5) + IDT_DESC_IGD_TYPE)
#define IDT_DESC_ATTR_DPL3          ((IDT_DESC_P << 7) + (IDT_DESC_DPL3 << 5) + IDT_DESC_IGD_TYPE)


#define EFLAGS_MBS	(1 << 1)	// 此项必须要设置
#define EFLAGS_IF_1	(1 << 9)	// if为1,开中断
#define EFLAGS_IF_0	0		// if为0,关中断
#define EFLAGS_IOPL_3	(3 << 12)	// IOPL3,用于测试用户程序在非系统调用下进行IO
#define EFLAGS_IOPL_0	(0 << 12)	// IOPL0

#define NULL                        ((void*)0)
#define DIV_ROUND_UP(X, STEP) ((X + STEP - 1) / (STEP))
#define bool                        int
#define true                        1
#define false                       0

#define PG_SIZE                     4096

#endif
